<?php

namespace app\api\middleware;

use app\api\service\JwtAuth;

use think\facade\Request;
use think\Response;
use think\exception\HttpResponseException;

class Api
{

    /**
     * 允许的请求头常量
     */
    private const ALLOWED_HEADERS = [
        'Authorization', 'Sec-Fetch-Mode', 'DNT', 'X-Mx-ReqToken', 'Keep-Alive', 'User-Agent',
        'If-Match', 'If-None-Match', 'If-Unmodified-Since', 'X-Requested-With', 'If-Modified-Since',
        'Cache-Control', 'Content-Type', 'Accept-Language', 'Origin', 'Accept-Encoding', 'Access-Token',
        'token', 'version'
    ];

    public function handle($request, \Closure $next)
    {

        // 设置跨域头
        $this->setCorsHeaders();

        // 如果是OPTIONS请求，直接返回响应
        if (strtoupper($request->method()) === 'OPTIONS') {
            return response();
        }

        // 获取当前控制器和方法
        $controller = strtolower($request->controller());
        $action = strtolower($request->action());

        // 定义免登录接口白名单（模块/控制器/方法）
        $whiteList = [
            'index/index',  // 示例：Index 控制器下的 index 方法
            'index/config',
            'index/about',
            'index/recyclingclass',
            'index/adlist',
            'index/policy',
            'article/index',
            'article/answer',
            'user/login',
            'user/register',
            'user/logout',
            'wechat/mnplogin',
            'user/loginout',
            'upload/upimage',
            'order/otherorderlist'
        ];

        $currentRoute = "{$controller}/{$action}";

        // 如果是白名单中的接口，跳过 token 鉴权
        if (in_array($currentRoute, $whiteList)) {
            return $next($request);
        }

        $token = Request::header('token');
        if ($token) {
            // 1. 格式校验
            if (count(explode('.', $token)) !== 3) {
                $this->result([], 0, -1, 'token格式错误');
            }

//            try {
            // 2. 获取 JwtAuth 实例并验证 Token
            $jwtAuth = JwtAuth::getInstance();
            // checkToken 返回解码后的对象（$flag = true）
            $decoded = $jwtAuth->checkToken(true, $token);

            // 3. Token 有效，继续执行后续逻辑
            return $next($request);
//            } catch (\Firebase\JWT\ExpiredException $e) {
//                // 捕获 Token 过期异常
//                $this->result([], 0, -1, 'token已过期');
//            } catch (\Firebase\JWT\SignatureInvalidException $e) {
//                // 捕获签名无效异常
//                $this->result([], 0, -1, '签名无效');
//            } catch (\Exception $e) {
//                // 其他错误统一处理
//                $this->result([], 0, -1, 'token验证失败: ' . $e->getMessage());
//            }
        } else {
            $this->result([], 0, -1, 'token不能为空');
        }

        return $next($request);
    }

    /**
     * 返回封装后的API数据到客户端
     * @param mixed $data 要返回的数据
     * @param integer $show 是否显示返回信息
     * @param integer $code 返回的code
     * @param mixed $msg 提示信息
     * @param string $type 返回数据格式
     * @param array $header 发送的Header信息
     * @return Response
     */
    protected function result($data, int $show = 0, int $code = 0, $msg = '', string $type = '', array $header = []): Response
    {
        $result = [
            'code' => $code,
            'show' => $show,
            'msg' => $msg,
            'time' => time(),
            'data' => $data,
        ];

        $type = $type ?: 'json';
        $response = Response::create($result, $type)->contentType('application/json', 'utf-8')->header($header);

        throw new HttpResponseException($response);
    }

    /**
     * @notes 设置跨域头信息
     * @return void
     */
    private function setCorsHeaders(): void
    {
        $headers = [
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Headers' => implode(', ', self::ALLOWED_HEADERS),
            'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, post',
            'Access-Control-Max-Age' => '1728000',
            'Access-Control-Allow-Credentials' => 'true'
        ];

        foreach ($headers as $key => $value) {
            header("$key: $value");
        }
    }

}
